// 初始化牌堆函数
function initializeDeck() {
// 清空操作日志
document.getElementById('log').innerHTML = '';
log("牌堆初始化开始");
// 重置所有牌堆相关变量
deck = [];
drawnCards = [];
discardPile = [];
hand = [];
document.getElementById('deck').innerHTML = ''; // 清空牌堆显示区域
reshuffleUsed = 0; // 重置脚气卡使用次数
phase = ''; // 重置游戏阶段
lastUsedCard = null; // 重置最后使用的卡牌
peachCount = 1; // 重置桃使用次数
wineCount = 1; // 重置酒使用次数
// 使用外部定义的standardDeck(在card.js中)创建牌堆
standardDeck.forEach(card => {
// 处理每张卡牌的花色和点数
card.suits.forEach(suitStr => {
// 使用正则表达式解析花色和点数
const match = suitStr.match(/^([♠♥♣♦]️?)([JQKA]|\d+)$/);
if (match) {
const suitPart = match[1]; // 提取花色部分
let point = match[2]; // 提取点数部分
// 将字母点数转换为数字
switch (point) {
case 'J':
point = 11;
break;
case 'Q':
point = 12;
break;
case 'K':
point = 13;
break;
case 'A':
point = 1;
break;
default:
point = parseInt(point, 10); // 数字点数直接转换为整数
}
// 根据卡牌数量创建多个副本
for (let i = 0; i
< card.count; i++) {
// 创建卡牌对象并添加到牌堆
deck.push({
name: card.name, // 卡牌名称
suit: suitPart, // 花色
point: point, // 点数
uid: CryptoJS.lib.WordArray.random(16).toString() // 唯一ID
});
}
}
});
});
// 重置武器和攻击状态
currentWeapon = null;
killCount = 2;
hasZhugeLianNu = false;
// 更新状态显示
updateStatus();
// 洗牌
shuffleDeck();
// 生成牌堆MD5
generateDeckMD5();
// 更新MD5显示
updateMD5Display();
// 生成牌堆AES
generateDeckAES();
// 更新AES显示
updateAESDisplay();
// 更新剩余牌数显示
updateRemaining();
// 开始游戏
startGame();
log("牌堆初始化完成");
}
// 洗牌函数
function shuffleDeck() {
// Fisher-Yates洗牌算法
for (let i = deck.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[deck[i], deck[j]] = [deck[j], deck[i]];
}
// 如果装备的武器不在牌堆中,重置武器状态
if (!deck.some(c => c.name === currentWeapon)) {
currentWeapon = null;
hasZhugeLianNu = false;
killCount = 2;
}
// 重置桃和酒的使用次数
peachCount = 1;
document.getElementById('peach-counter').textContent = `桃可用次数:1`;
wineCount = 1;
// 更新状态
updateStatus();
// 生成新的AES编码
generateDeckAES();
updateAESDisplay();
}
// 脚气卡使用(重新洗牌)
function handleReshuffle() {
// 验证脚气卡使用条件
if (!validateReshuffle()) return;
// 记录日志
log(`开始使用脚气卡(当前已用${reshuffleUsed}次)`);
// 回收当前手牌
const currentDrawn = hand.splice(-4, 4);
log(`回收手牌:${currentDrawn.map(c => c.name).join(', ')}`);
// 将手牌放回牌堆顶部
deck.unshift(...currentDrawn);
// 洗牌
shuffleDeck();
// 更新脚气卡使用次数
reshuffleUsed++;
log(`脚气卡洗牌完成(${reshuffleUsed}/${MAX_RESHUFLE}次)`);
// 清空已抽取牌堆
discardPile.push(...drawnCards);
drawnCards = [];
// 重新抽牌
drawCards(4);
log(`重新抽取4张牌,剩余牌堆:${deck.length}张`);
// 更新界面
updateCounter();
updateReshuffleButton();
}
function initializeDeck() {
// 清空操作日志
document.getElementById('log').innerHTML = '';
log("牌堆初始化开始");
// 重置预留的AK
reservedInitialAK = null;
// 重置所有牌堆相关变量
deck = [];
drawnCards = [];
discardPile = [];
hand = [];
document.getElementById('deck').innerHTML = ''; // 清空牌堆显示区域
reshuffleUsed = 0; // 重置脚气卡使用次数
phase = ''; // 重置游戏阶段
lastUsedCard = null; // 重置最后使用的卡牌
peachCount = 1; // 重置桃使用次数
wineCount = 1; // 重置酒使用次数
// 使用外部定义的standardDeck(在card.js中)创建牌堆
standardDeck.forEach(card => {
// 处理每张卡牌的花色和点数
card.suits.forEach(suitStr => {
// 使用正则表达式解析花色和点数
const match = suitStr.match(/^([♠♥♣♦]️?)([JQKA]|\d+)$/);
if (match) {
const suitPart = match[1]; // 提取花色部分
let point = match[2]; // 提取点数部分
// 将字母点数转换为数字
switch (point) {
case 'J':
point = 11;
break;
case 'Q':
point = 12;
break;
case 'K':
point = 13;
break;
case 'A':
point = 1;
break;
default:
point = parseInt(point, 10); // 数字点数直接转换为整数
}
// 根据卡牌数量创建多个副本
for (let i = 0; i < card.count; i++) {
// 创建卡牌对象并添加到牌堆
deck.push({
name: card.name, // 卡牌名称
suit: suitPart, // 花色
point: point, // 点数
uid: CryptoJS.lib.WordArray.random(16).toString() // 唯一ID
});
}
}
});
});
// 重置武器和攻击状态
currentWeapon = null;
killCount = 2;
hasZhugeLianNu = false;
// 更新状态显示
updateStatus();
// 洗牌
shuffleDeck();
// 生成牌堆MD5
generateDeckMD5();
// 更新MD5显示
updateMD5Display();
// 生成牌堆AES
generateDeckAES();
// 更新AES显示
updateAESDisplay();
// 更新剩余牌数显示
updateRemaining();
// 开始游戏
startGame();
log("牌堆初始化完成");
}
相比随机洗牌版initializeDeck()函数:
reservedInitialAK = null;初始化操作function shuffleDeck() {
log("开始特殊规则洗牌");
// 1. 分类卡牌
const heil = []; // 黑利牌
const hl = []; // 红利牌
const other = []; // 其他牌
// 定义黑利牌列表
const heilCards = [
"闪", "桃", "雌雄双股剑", "青龙偃月刀", "青釭剑",
"丈八蛇矛", "麒麟弓", "贯石斧", "方天画戟",
"寒冰剑", "古锭刀", "朱雀羽扇"
];
// 定义红利牌列表
const hlCards = ["无中生有", "顺手牵羊", "过河拆桥"];
deck.forEach(card => {
if (heilCards.includes(card.name)) {
heil.push(card);
} else if (hlCards.includes(card.name)) {
hl.push(card);
} else {
other.push(card);
}
});
// 日志分类结果
log(`分类完成: heil=${heil.length}|hl=${hl.length}|other=${other.length}${reservedInitialAK ? '|ak_reserved' : ''}`);
// 2. 对每类牌进行内部洗牌
shuffleArray(heil);
shuffleArray(hl);
shuffleArray(other);
// 3. 构建新牌堆:红利牌 -> 其他牌 -> 黑利牌
deck = [...hl, ...other, ...heil];
// 4. 额外的洗牌:将前10张和后10张随机交换
const swaps = Math.min(10, Math.floor(deck.length / 2));
for (let i = 0; i < swaps; i++) {
const j = deck.length - 1 - i;
[deck[i], deck[j]] = [deck[j], deck[i]];
}
// 5. 如果之前预留了AK,添加到日志但不放回牌堆
if (reservedInitialAK) {
log(`预留的诸葛连弩不在牌堆中,将出现在初始手牌`);
}
// 6. 如果装备的武器不在牌堆中,重置武器状态
if (!deck.some(c => c.name === currentWeapon)) {
currentWeapon = null;
hasZhugeLianNu = false;
killCount = 2;
}
// 重置桃和酒的使用次数
peachCount = 1;
document.getElementById('peach-counter').textContent = `桃可用次数:1`;
wineCount = 1;
// 更新状态
updateStatus();
// 生成新的AES编码(牌堆不包含预留的AK)
generateDeckAES();
updateAESDisplay();
log("特殊规则洗牌完成");
}
相比随机洗牌版shuffleDeck()函数: